/* ..

====================================================
Example: benchmarking OpenCV morphological functions
====================================================

	:File:			morph_bench.c
	:Description:	benchmark morphological operations, using OpenCV
	:Author:		Kay-Uwe Kirstein
	:Version:		0.1
	
*/

#include <stdio.h>
#include <time.h>
#include <omp.h>

#include "opencv/cv.h"
#include "opencv/highgui.h"

// main function
int main(int argc, char** argv) {
	
	IplImage	*ff = 0;
	IplImage	*res1 = 0;
	IplImage	*res2 = 0;
	CvSize		size;

	// IplConvKernel	*kernel3, *kernel5, *kernel20;
	IplConvKernel*	kernels[3];
	
	const int	count = 5000;
	int			i, k;
	const char*	filename = "examples\\lena.jpg";
	const char*	filename2 = "examples\\lena_dilate_c.tif";

	time_t		starttime, endtime;
	time_t		all_start, all_end;
	int			num_threads, id_thread;
	
	// get grayscale image
	ff = cvLoadImage(filename, CV_LOAD_IMAGE_GRAYSCALE);
	if(!ff) {
		printf("Sorry, could not open %s\n", filename);
		exit(0);
	}
	
	size = cvSize(ff->width, ff->height);

	// print some infos
	printf("Testfile: %s\n", filename);
	printf("Depth: %d\tChannels: %d\n", ff->depth, ff->nChannels);
	printf("Width: %d\tHeight: %d\n", ff->width, ff->height);
	
	// generate kernels
	kernels[0] = cvCreateStructuringElementEx(3, 3, 1, 1, CV_SHAPE_RECT, NULL);
	kernels[1] = cvCreateStructuringElementEx(5, 5, 2, 2, CV_SHAPE_RECT, NULL);
	kernels[2] = cvCreateStructuringElementEx(20, 20, 10, 10, CV_SHAPE_RECT, NULL);
	
	time(&all_start);
	// loop thru different kernel sizes
	# pragma omp parallel for private(res1, res2, starttime, endtime)
	for(k=0; k<3; k++) {
		
		// loop without memory preallocation
/*		time(&starttime);
		//# pragma omp parallel for private(res1, starttime, endtime)
		for(i=0; i<count; i++) {
			res1 = cvCreateImage(size, IPL_DEPTH_8U, 1);
			cvDilate(ff, res1, kernels[k], 1);
			cvReleaseImage(&res1);
		}
		time(&endtime);
		printf("%d loops with kernel %d without memory preallocation: %ld sec elpsed.\n", count, k, endtime-starttime); */
		
		// loop with memory preallocation
		time(&starttime);
		res2 = cvCreateImage(size, IPL_DEPTH_8U, 1);
		//# pragma omp parallel for default(none) private(res2, starttime, endtime)
		for(i=0; i<count; i++) {
			cvDilate(ff, res2, kernels[k], 1);
		}
		time(&endtime);
		printf("%d loops with kernel %d with memory preallocation: %d sec CPU time.\n", count, k, endtime-starttime);
		
		id_thread = omp_get_thread_num();
		if(id_thread == 0) num_threads = omp_get_num_threads();
	}

	res2 = cvCreateImage(size, IPL_DEPTH_8U, 1);
	cvDilate(ff, res2, kernels[2], 1);
	cvSaveImage(filename2, res2, NULL);
	cvReleaseImage(&res2);
	
	time(&all_end);
	printf("Overall %ld sec elapsed with %d threads.\n", all_end-all_start, num_threads);
	
	// clean up
	cvReleaseImage(&ff);
	for(k=0; k<3; k++) {
		cvReleaseStructuringElement(&kernels[k]);
	}
	
}

	